package com.chelsea;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class PicturePanel extends JPanel implements MouseListener, MouseMotionListener{
	
	BufferedImage buffImg, bi;
    File file;
    int picHeight = 400, picWidth = 400;
    
    int tagX = -1, tagY = -1, tagSize = 100;
    int nameX = -1, nameY = -1;
    String tagName;
   
    Screen screen;
	private boolean isAddingTag = false;
	private boolean isHoveringTag = false;
    
	public PicturePanel(Screen s){
		super();
		
		file = this.getFileOrDirectory();
		this.setPreferredSize(new Dimension(400,450));
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.screen = s;
	}
	
	public void setTagX(int tagX) {
		this.tagX = tagX;
	}

	public void setTagY(int tagY) {
		this.tagY = tagY;
	}

	private File getFileOrDirectory(){
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		
		int result = fileChooser.showOpenDialog(this);
		
		if (result == JFileChooser.CANCEL_OPTION)
			System.exit(1);
		
		File fileName = fileChooser.getSelectedFile();
		
		if ( (fileName == null) || (fileName.getName().equals(""))){
			JOptionPane.showMessageDialog(this, "Invalid Name", "Invalid Name", JOptionPane.ERROR_MESSAGE);
			System.exit(1);
		}
		return fileName;
	}
	
	public void hideSquare(){
		this.setTagX(-1);
		this.setTagY(-1);
		this.setNameX(-1);
		this.setNameY(-1);
		this.repaint();
	}
	
	public int getNameX() {
		return nameX;
	}

	private void setNameX(int nameX) {
		this.nameX = nameX;
	}

	public int getNameY() {
		return nameY;
	}

	private void setNameY(int nameY) {
		this.nameY = nameY;
	}

	public void paint(Graphics g){
		super.paint(g);
		
		 try {
			buffImg = ImageIO.read(file);
			//int picHeight = buffImg.getWidth(null);
	        //int picWidth = buffImg.getHeight(null);
			picHeight = (int)this.getSize().getHeight();
			picWidth = (int)this.getSize().getWidth();
	        bi = new BufferedImage(picHeight, picWidth, BufferedImage.TYPE_INT_ARGB);
	        Graphics gImg = bi.getGraphics();
	        gImg.drawImage(buffImg, 0, 0, null);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, "Cannot open file!");
			e.printStackTrace();
		}
        
         Graphics2D g2d = (Graphics2D)g;
         g2d.drawImage(bi, 0, 0, null);
         
         //is mouse hovering over an existing tag?
         if (this.isHoveringTag == false) {
        	 //draw square for add and viewing by click
        	 if (tagX != -1 && tagY != -1)
        		 this.drawSquare(g2d);
         }
         
         //draw tagname!
         if (nameX != -1 && nameY != -1)
        	 this.drawName(g2d);
         
	}
	
	private void drawSquare(Graphics2D g2d){
		g2d.setColor(new Color(134,156, 247));
   	 	g2d.draw(new Rectangle2D.Double(tagX+3, tagY+3, tagSize-6, tagSize-6));
   	 	g2d.setColor(Color.white);
   	 	g2d.setStroke( new BasicStroke(5.0f, 
   			 						BasicStroke.CAP_ROUND,
   			 						BasicStroke.JOIN_ROUND));
   	 	g2d.draw(new Rectangle2D.Double(tagX, tagY, tagSize, tagSize));
   	 	g2d.setColor(Color.black);
	}

	private void drawName(Graphics2D g2d){
		//if (isHoveringTag == true){
			g2d.setColor(Color.black);
			g2d.fillRect(nameX - 5, nameY - 13, 70, 20);
			g2d.setColor(Color.white);
		//}
			
		g2d.setFont(new Font("Cambria", Font.BOLD, 15));
		g2d.drawString(tagName, nameX, nameY);
	}
	
	public void drawSquare(int x, int y){
		//draw the square
		this.setTagX(x - 50);
		this.setTagY(y - 50);
		this.repaint();
	}

	public void drawNameViewByClick (int x, int y){
		this.setNameX(x - (tagSize/2 - 10));
		this.setNameY(y + (tagSize/2 + 9));
		this.repaint();
	}
	
	public void drawNameByHover(int x, int y, String name){
			//draw near the mouse's pointer
			this.tagName = name;
			this.setNameX(x - 10);
			this.setNameY(y + 5);
			
		this.repaint();
		//this.tagName = "";
	}
	
	public void hideNameByHover()
	{
		this.tagName = "";
		this.setNameX(-1);
		this.setNameY(-1);
		
		this.repaint();
		
	}
	public void displayTagByClick(Tag tag) {
		// TODO Auto-generated method stub
	
		if(tag.isToggle()){
			this.drawSquare(tag.getTagX(), tag.getTagY());
			//this.tagName = tag.getName();
			//this.drawNameViewByClick(tag.getTagX(), tag.getTagY());
		}
			
		else
			this.hideSquare();
		this.repaint();
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		this.initTagAddingEvent();
		this.screen.addTag(e.getX(), e.getY());
	}

	public boolean isAddingTag() {
		return isAddingTag;
	}


	public void endTagAddingEvent(){
		this.isAddingTag = false;
	}


	public void initTagAddingEvent(){
		this.isAddingTag = true;
	}
	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		if (isAddingTag  == false){
			
			Tag tag = screen.viewTagByHover(arg0.getX(), arg0.getY(), tagSize);
			
			if (tag != null)
			{
				this.isHoveringTag = true;
				this.drawNameByHover(tag.getTagX(), tag.getTagY(), tag.getName());
			}
			else
			{
				//tell panel to not display the name because pointer is outside bounds already
				this.isHoveringTag = false;
				this.hideNameByHover();
			}
		}
	}



	

	

}
